5分钟带你了解Python2和3的区别|从此不再纠结
这是菜鸟学Python的第113篇原创文章
阅读本文大概需要5分钟
下面是一篇来自小密圈的私密分享,小密圈的很多小伙伴问我,关于学Py2.x还是3的问题, 我觉得应该放在公号里面分享一下. 简单说:如果是新手建议直接上3.因为Py3是未来的大势所趋,Py2.7现在只是在维护,不会增加新的功能. 如果是老鸟的话,或者已经上手了Python2的同学,建议继续深入挖掘Py2的技巧和熟练操作.Py2和3的精髓和招式大体相同,其实我一直是2,3混用的,没有感觉到特别大的不适应(除了print)!即使有不同,网上搜一下很快搞定的.说这么多,我还是把2和3的主要区别整理一下给大家,希望能给你一些帮助!
个人的看法:
你在Py2上学了那么长的时候,那么多库和模块你都能掌握.过度到Python3 so easy!而且现在还有2to3的转换神器,让你轻松兼容两套环境!如果非要我说我为啥还一直念念不舍Py2的话,主要还是用习惯了!我自己的电脑上有两套Py2和Py3的环境,一般看我工作的内容进行切换选择.
01
1.Print函数
这个可能是Py2和Py3最大的区别,很多用惯了2的人很不习惯!为啥到3上一定要加一个().因为print 从语句变为函数,我们来看一下Py3中print的源码
我们看一下print的源码,发现*args其实就是你输入的字符串,一个或者多个字符串. 而.sep表示默认用空格区分,而end表示换行,也就是我默认给你换行的
1).py3里面所有额print 都加()
print ("hi","python")
>>hi python #默认sep为空格换行
print ("hi","python",sep="*")
>>hi*python
2).关于换行
py3.x
print ("hi")
print ("python")
>>
hi
python
print ("hi",end="")
print ("python")
>>hipython
py2.x #用,来表示不换行
print "hi",
print "python"
>>hi python
02
字符串
字符串也就是文本,这个问题一直在py2里面没有很好的处理。在py3里面彻底的解决了。Python 3最重要的改动除了print,大概要算是对文本和二进制数据作了更为清晰的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示
1).编码问题
Py2.x:里面默认是编码是ASCII,而
import sys
print (sys.getdefaultencoding())
>>ascii
Py3.x:里面默认是utf-8
import sys
print (sys.getdefaultencoding())
>>utf-8
2).字符串类型
py2 :里面的字符串有两种str()类型和unicode类型
s1="大家好"
print type(s1)
>><type 'str'>
s2=u"大家好"
print type(s2)
>><type 'unicode'>
py3:里面的字符串只有一种str()类型,这里的str()类型等价于py3里面的unicode类型
s1="大家好"
print (type(s1))
>>
<class 'str'>
s2=u"大家好"
print (type(s2))
>>
<class 'str'>
3).py3新增bytes类型
s3= b'china'
print (type(s3))
>><class 'bytes'>
这个bytes是什么鬼,为啥要有字节类型,其实主要处理二进制数据.
str对象和bytes对象可以使用encode()/decode()方法相互转化
b=b'python'
print (b)
print (type(b))
>>
b'python'
<class 'bytes'>
s = b.decode()
print (s)
print (type(s))
>>
python
<class 'str'>
b2=s.encode()
print (b2)
print (type(b2))
>>
b'python'
<class 'bytes'>
03
比较判断和除法
1.比较判断
Py2.x:不等运算符用两种!=和<>
Py3.x:里面不等判断只有!=
其实我好像一般不怎么用<>,因为!=打字更快一些,哈哈
2.类型比较
Py2.x:当比较两个变量的时候,比如x<y,如果遇到x和y的类型不匹配,py2直接返回bool结果
感悟:很明显x是列表,而2是整形,二者根本不能比较. py2直接返回False,不严谨!py3对这点改良了
Py3.x:当比较两个变量的时候,比如x<y,如果遇到x和y的类型不匹配,py3直接抛异常
3.除法
Py2.x:整形除法的时候,返回它只取整数部分
print 10/3
>>3
如果要小数必须要在开头加__future__
from __future__ import division
print 10/3
>>3.33333333333
如果只想保留小数点后面2位
print round(10/3,2)
>>3.33
Py3.x:直接默认在整形数做除法,返回用浮点
print (10/3)
>>3.3333333333333335
print (10//3)
>>3 #//表示取整
print (round(10/3,2))
>>3.33
04
输入函数和可迭代式赋值
1.输入函数
Py2.x:有两种,获取用户输入的函数
something = input('Enter text: ')
something = raw_input('Enter text: ')
Py3:只有input,删除了raw_input
感悟:看的出Py3里面的input其实就是相当于2里面的raw_input(),名字取input更简洁。后面继续看会发现Py3里面有很多类似的这样的取代.
2.赋值变量,扩展的可迭代解包
py2:
a,b,*res=[1,2,3,4] ,这样写是会报错的
但是py3里面写就合法,这样的写法非常简洁,比如我只想先分析一个列表的头部变量,剩下的我另外处理,用*res就非常方便的切分.
a,b,*res=[1,2,3,4]
print (a)
print (b)
print (res)
>>
1
2
[3, 4]
05
异常处理
Py3里面的异常改动蛮多,总结有3小点:
1).异常的继承
py2.x,所有类型的对象只要发生异常就抛出,不需要继承BaseException
py3.x,只有继承自BaseException的对象才可以被抛出,更加严格规范
2).异常的语法
py2:异常我们有的是可以偷懒写成
try:
10/0
except Exception , e:
print 'error',e
但是在py3里面必须要加上as,不然会报语法错误
try:
10/0
except Exception as e:
print ('error',e)
感悟:很明显,py3更注重pythonic风格的编码
3).异常的捕获
py2:里面捕获异常的时候,我们可以raise Exception, args
try:
10/0
except Exception ,e:
raise ValueError,e
>>
raise ValueError,e
ValueError: integer division or modulo by zero
py3:里面捕获异常的时候,我们必须写成raise Exception(args)
try:
10/0
except Exception as e:
raise ValueError(e)
>>
raise ValueError(e)
ValueError: division by zero
是不是感觉更舒服了更合理了!
06
字典和高阶函数
1.字典
py3.x :字典里面dict.keys(),dict.items()和dict.values()方法返回迭代器
去掉了py2.x里面的iterkeys()
去掉的dict.has_key(),py3.x用in替代它吧
2.高阶函数
py2.x:zip(),map()和filter()直接返回列表
py3.x:zip(),map()和filter()直接返回迭代器,如果要变列表,必须要加list
py2.x:
s1=[1,2,3]
s2=['a','b','c']
print (zip(s1,s2))
>>[(1, 'a'), (2, 'b'), (3, 'c')]
py3.x:
s1=[1,2,3]
s2=['a','b','c']
print (zip(s1,s2))
>><zip object at 0x00000000027CF788>
print (list(zip(s1,s2)))
>>[(1, 'a'), (2, 'b'), (3, 'c')]
其他的两个高阶函数类似
07
range/xrange
range应该是我们在Python最最常用的网红,Py2和3对它进行的改造
1.Py2.x
1).range 和xrange都是经常使用的,特别是range()返回一个列表
print range(3)
>>
[0, 1, 2]
2).xrange()一般用来创建迭代对象
print [x for x in xrange(3)]
>>[0, 1, 2]
print list(xrange(3))
>>[0, 1, 2]
2.Py3.x
3).里面xrange()不存在了,只有range().而range()相当于py2.x里面的xrange()
print (range(3))
>>range(0, 3)
想要获取列表,必须要加list
print (list(range(3)))
>>[0, 1, 2]
感悟:其实主要对内存的节约,py2.x里面比如你range(10000),一下子就生成一个长度为10000的内存空间,而py3的 range(1000)返回的不是列表是一个迭代器,你用的时候一个一个循环取出来,对内存节省很多
08
类
1.关于类
py2.x:里面子类继承父类经常要写super这个函数,就是子类初始的话要记得初始化父类,这时super()里面要填一些参数
py3.x:里面直接简化了这个过程,省掉super()里面的参数,更简洁更Pythonic
09
生成器函数
py2.x:生成器函数需要生成另外一个生成器生成的值,一般需要嵌套的值
py3.x:增加了一个yield from ,可以简化操作,生成器函数自动把操作交给可以接收到的各个迭代对象处理
10
其他
1).多个模块被改名
_winreg->winreg
ConfigParser->configparser
copy_reg->copyreg
Queue->queue
SocketServer->socketserver
repr->reprlib
其中比较常用的是Queue和SocketServer
2).取消了exec语句
留下了exec()函数.其实py2.7已经开始用exec()函数了.
3.string模块有改动
string.letters
string.lowercase
string.uppercase
上面3个都被移除了,用string.ascii_letters代替
string.ascii_letters.lower()
string.ascii_letters.upper()
结论:
py2和py3最大的区别在print和字符串,其他的都是一些小的修改。但是虽然是小的调整,静心下来思考一下,透过现象看本质。发现py3对语言上更加严谨更严格,可读性更高,代码更简洁更注重安全,越来越Pythonic,处处体现工匠精神,我也衷心希望Python越来越好!
通过上面的分析,如果对py2非常熟悉的同学,上手py3大概只要几个小时.所以千万不要再纠结学py2还是py3,而浪费宝贵的学习时间!
长按二维码,加入小密圈
第二期训练营马上开始
期待你的加入
来源 | 菜鸟学Python
作者 | xinxin
本文章为菜鸟学Python独家原创稿件,未经授权不得转载